﻿//////////////////////////////////////////////////////////////////////////////
//                                                                          //
// Copyright 2010 ZGDev Software                                            //
//                                                                          //
// Licensed under the Apache License, Version 2.0 (the "License");          //
// you may not use this file except in compliance with the License.         //
// You may obtain a copy of the License at                                  //
//                                                                          //
//   http://www.apache.org/licenses/LICENSE-2.0                             //
//                                                                          //
// Unless required by applicable law or agreed to in writing, software      //
// distributed under the License is distributed on an "AS IS" BASIS,        //
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //
// See the License for the specific language governing permissions and      //
// limitations under the License.                                           //
//                                                                          //
//////////////////////////////////////////////////////////////////////////////

using System;
using System.Windows;
using System.Windows.Controls;
using System.Threading;

namespace ZGDev.FormSpark
{
    /// <summary>
    /// The main thread dispatcher to be used in WPF applications.
    /// </summary>
    /// <remarks>
    /// This control MUST be added to the main application window, or some other
    /// control that lives for the duration of the application.
    /// </remarks>
    /// <seealso cref="IMainThreadDispatcher"/>
    internal partial class MainThreadCallerWPFControl : Control, IMainThreadDispatcher
    {
        /// <summary>
        /// Initializes the object instance.
        /// </summary>
        public MainThreadCallerWPFControl()
        {
            InitializeComponent();
            Dispatch.MainThreadDispatcher = this;
        }

        /// <summary>
        /// Performs the main thread callback.
        /// </summary>
        /// <param name="entity">The entity that requested the callback.</param>
        /// <param name="arg">The argument to be sent to th entity.</param>
        private void doCallback(IMainThreadEntity entity, object arg)
        {
            entity.MainThreadCallback(arg);
        }

        #region IMainThreadDispatcher Members

        /// <summary>
        /// Determines if a dispatch is needed (a dispatch is not needed if the caller is executing
        /// on the main thread already).
        /// </summary>
        /// <returns>True if the caller is not executing on the main thread, false otherwise.</returns>
        public bool GetNeedsDispatch()
        {
            return this.Dispatcher.Thread != Thread.CurrentThread;
        }

        /// <summary>
        /// Requests that an entity be called called back on the main thread.
        /// </summary>
        /// <param name="entity">The entity that is to be called back.</param>
        /// <param name="arg">The (optional) argument to pass to the entity.</param>
        public void RequestMainThreadCallback(IMainThreadEntity entity, object arg)
        {
            this.Dispatcher.Invoke(new MainThreadCallbackDelegate(this.doCallback), entity, arg);
        }

        #endregion
    }
}
